using System;
using System.ComponentModel;
using System.Runtime.Serialization;

using SharpGL.Media3D;

namespace SharpGL.SceneGraph.Lighting
{
	/// <summary>
	/// a spotlight has a direction and a spot cutoff.
	/// </summary>
    [DataContract()]
	public class Spotlight : Light
    {
        #region Private Fields
        
        /// <summary>
        /// The spotlight cutoff value (between 0-90 for spotlights, or 180 for a 
        /// simple light).
        /// </summary>
        [DataMember()]
        private float spotCutoff = 45.0f;

        /// <summary>
        /// a Vector describing the direction of the spotlight.
        /// </summary>
        [DataMember()]
        private Vector3D direction = new Vector3D(0, 1, 0);

        #endregion Private Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Spotlight"/> class.
        /// </summary>
        public Spotlight()
		{
            Name = "Spotlight";
		}

        #endregion Constructors

        #region Public Methods

        /// <summary>
        /// This function sets all of the lights parameters into OpenGL.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
		public override void Bind(OpenGL gl)
		{
            //  Call the base (setting ambient etc).
            base.Bind(gl);

            if (OpenGL.IsValidContext(gl))
            {
                //  Is the light on?
                if (On)
                {
                    //  Set the spot parameters.
                    gl.Light(GLCode, OpenGL.GL_SPOT_CUTOFF, spotCutoff);
                    gl.Light(GLCode, OpenGL.GL_SPOT_DIRECTION, direction);
                }
            }
		}

        #endregion Public Methods

        #region Public Properties

        /// <summary>
        /// Gets or sets the direction.
        /// </summary>
        /// <value>
        /// The direction.
        /// </value>
        [Category("Light"), Description("The spotlight direction.")]
        public Vector3D Direction
		{
			get
            {
                return direction;
            }
            set
            {
                if (direction != value)
                {
                    direction = value;

                    NotifyPropertyChanged("Direction");
                }
            }
		}

        /// <summary>
        /// Gets or sets the spot cutoff.
        /// </summary>
        /// <value>
        /// The spot cutoff.
        /// </value>
        [Category("Light"), Description("The spotlight cutoff.")]
		public float SpotCutoff
		{
			get
            {
                return spotCutoff;
            }
            set
            {
                if (spotCutoff != value)
                {
                    spotCutoff = value;

                    NotifyPropertyChanged("SpotCutoff");
                }
            }
        }

        #endregion Public Properties
    }
}
